/**
 * The MIT License (MIT)
 *
 * Copyright (c) 2014 abel533@gmail.com
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */

package com.eppear.jpfm.framework.service.impl;

import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;

import com.eppear.jpfm.framework.common.DtPage;
import com.eppear.jpfm.framework.dao.BaseDao;
import com.eppear.jpfm.framework.service.IService;
import com.eppear.jpfm.framework.util.datatables.DtParm;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;

import tk.mybatis.mapper.common.Mapper;

/**
 * Created by liuzh on 2014/12/11.
 */
public abstract class BaseService<T> implements IService<T> {

    @Autowired
    protected Mapper<T> mapper;
    @Autowired
	protected BaseDao baseDao;

    public Mapper<T> getMapper() {
        return mapper;
    }

    /**
     * 查询全部结果
     * @see com.eppear.jpfm.service.IService#select()
     */
    public List<T> select(){
    	return this.mapper.selectAll();
    }
    /**
     * 根据实体中的属性值进行查询，查询条件使用等号
     * @see com.eppear.jpfm.service.IService#select(java.lang.Object)
     */
    @Override
    public List<T> select(T record){
    	return mapper.select(record);
    }
    /**
     * 根据主键字段进行查询，方法参数必须包含完整的主键属性，查询条件使用等号
     * @see com.eppear.jpfm.service.IService#selectByKey(java.lang.Object)
     */
    @Override
    public T selectByKey(Object key) {
        return mapper.selectByPrimaryKey(key);        
    }

    /**
     * @see com.eppear.jpfm.service.IService#selectByExample(java.lang.Object)
     */
    @Override
    public List<T> selectByExample(Object example) {
        return mapper.selectByExample(example);
    }
    
    /**
     * 分页-通用查询,根据实体中的属性值进行查询，查询条件使用等号
     * @see com.eppear.jpfm.service.IService#selectDtPage(java.lang.Object, java.lang.Integer, java.lang.Integer)
     */
    public DtPage selectDtPage(DtParm pageParm){
    	
    	//分页查询
        PageHelper.offsetPage(pageParm.getStart(),pageParm.getLength());
        List<T> data = mapper.selectAll();
        PageInfo page = new PageInfo(data);
        int total = ((Number)page.getTotal()).intValue();
        
        DtPage<T> result = new DtPage<T>();
        result.setDraw(pageParm.getDraw());
        result.setData(data);
        result.setRecordsTotal(total);
        result.setRecordsFiltered(total);        
    	return result;
    }
    
    /**
     * 分页-通用查询,根据实体中的属性值进行查询，查询条件使用等号
     * @see com.eppear.jpfm.service.IService#selectDtPage(java.lang.Object, java.lang.Integer, java.lang.Integer)
     */
    public DtPage selectDtPage(T record,DtParm pageParm){
    	
    	//分页查询    	
    	PageHelper.offsetPage(pageParm.getStart(),pageParm.getLength());
        List<T> data = mapper.select(record);
        PageInfo page = new PageInfo(data);
        int total = ((Number)page.getTotal()).intValue();
        
        DtPage<T> result = new DtPage<T>();
        result.setData(data);
        result.setRecordsTotal(total);
        result.setRecordsFiltered(total);        
    	return result;
    }
    
    /**
     * 分页-通用查询,<br>
     * 根据实体中的属性值进行查询，查询条件使用等号<br>
     * 用于子类中需要分页的方法
     * @see com.eppear.jpfm.service.IService#selectDtPage(java.lang.Object, java.lang.Integer, java.lang.Integer)
     */
    public <T> DtPage selectDtPage(Mapper mp,DtParm pageParm){
    	
    	//分页查询
        PageHelper.offsetPage(pageParm.getStart(),pageParm.getLength());
        List<T> data = mp.selectAll();
        PageInfo page = new PageInfo(data);
        int total = ((Number)page.getTotal()).intValue();
        
        DtPage<T> result = new DtPage<T>();
        result.setDraw(pageParm.getDraw());
        result.setData(data);
        result.setRecordsTotal(total);
        result.setRecordsFiltered(total);        
    	return result;
    }
    
    /**
     * 分页-通用查询,根据实体中的属性值进行查询，查询条件使用等号
     * @see com.eppear.jpfm.service.IService#selectDtPage(java.lang.Object, java.lang.Integer, java.lang.Integer)
     */
    public<T> DtPage selectDtPage(Mapper mp,T record,DtParm pageParm){
    	
    	//分页查询
    	PageHelper.offsetPage(pageParm.getStart(),pageParm.getLength());
        List<T> data = mp.select(record);
        PageInfo page = new PageInfo(data);
        int total = ((Number)page.getTotal()).intValue();
        
        DtPage<T> result = new DtPage<T>();
        result.setData(data);
        result.setRecordsTotal(total);
        result.setRecordsFiltered(total);        
    	return result;
    }
    
    /**
     * 保存一个实体，null的属性也会保存，不会使用数据库默认值
     * @see com.eppear.jpfm.service.IService#save(java.lang.Object)
     */
    @Override
    public int save(T entity) {
        return mapper.insert(entity);
    }

    /**
     * 保存一个实体，null的属性不会保存，会使用数据库默认值
     * @see com.eppear.jpfm.service.IService#saveNotNull(java.lang.Object)
     */
    @Override
    public int saveNotNull(T entity){
    	return mapper.insertSelective(entity);
    }
    
    @Override
    public int delete(Object key) {
        return mapper.deleteByPrimaryKey(key);
    }

    /**
     * 根据主键更新实体全部字段，null值会被更新
     * @see com.eppear.jpfm.service.IService#update(java.lang.Object)
     */
    @Override
    public int update(T entity) {
        return mapper.updateByPrimaryKey(entity);
    }

    /**
     * 根据主键更新属性不为null的值
     * @see com.eppear.jpfm.service.IService#updateNotNull(java.lang.Object)
     */
    @Override
    public int updateNotNull(T entity) {
        return mapper.updateByPrimaryKeySelective(entity);
    }

   

    //TODO 其他自定义方法
    /**
	 * @Description
	 *   查询单条记录的方法
	 * @author JianFeng Zhang(张建锋)
	 * @date 2017-01-16 下午7:58:24
	 * @param sqlId SQL语句ID,即文件中的namespace.SQLID
	 * @param parameter  查询参数
	 * @return Map类型的记录,如果有多条,则会报错
	 */
    @Override
	public Map<String,Object> selectOneFromXML(String sqlId, Object parameter){
		return this.baseDao.selectOneFromXML(sqlId, parameter);
	}
	/**
	 * @Description
	 * 	查询单条记录的方法,用于无需SQL参数的情况
	 * @author JianFeng Zhang(张建锋)
	 * @date 2017-01-16 下午8:31:46
	 * @param sqlId SQL语句ID,即文件中的namespace.SQLID
	 * @return
	 */
    @Override
	public Map<String,Object> selectOneFromXML(String sqlId){
		return this.baseDao.selectOneFromXML(sqlId);
	}
	
	/**
	 * @Description
	 *         查询多条记录的方法
	 * @author JianFeng Zhang(张建锋)
	 * @date 2017-01-16 下午8:23:33
	 * @param sqlId SQL语句ID,即文件中的namespace.SQLID
	 * @param parameter 查询参数
	 * @return 类型为 List<Map>
	 */
    @Override
	public List<Map> selectFromXML(String sqlId, Object parameter){
		return this.baseDao.selectFromXML(sqlId, parameter);
	}
	
	/**
	 * @Description
	 * 查询多条记录的方法 ,用于无需SQL参数的情况
	 * @author JianFeng Zhang(张建锋)
	 * @date 2017-01-16 下午8:38:07
	 * @param sqlId SQL语句ID,即文件中的namespace.SQLID
	 * @return 类型为 List<Map>
	 */
    @Override
	public List<Map> selectFromXML(String sqlId){
		return this.baseDao.selectFromXML(sqlId);
	}
   
    /**
	 * 分页-通用查询,查询多条记录的方法
	 * @see com.eppear.jpfm.service.IService#selectFromXMLDtPage(java.lang.String, java.lang.Object, com.eppear.jpfm.framework.util.datatables.DtParm)
	 */
	public DtPage selectFromXMLDtPage(String sqlId, Object parameter,DtParm pageParm){
		
		//分页查询
		String orderBy = pageParm.getOrderBy();
		if (pageParm.getOrderable() && !"".equals(orderBy)){
			PageHelper.offsetPage(pageParm.getStart(),pageParm.getLength(),orderBy);
		}else{
			PageHelper.offsetPage(pageParm.getStart(),pageParm.getLength());
		}
        List<Map> data = baseDao.selectFromXML(sqlId, parameter);
        PageInfo page = new PageInfo(data);
        int total = ((Number)page.getTotal()).intValue();
        
        DtPage<Map> result = new DtPage<Map>();
        result.setDraw(pageParm.getDraw());
        result.setData(data);
        result.setRecordsTotal(total);
        result.setRecordsFiltered(total);        
    	return result;    	
    	 
	}
	
	/**
	 *   分页-通用查询,查询多条记录的方法,用于无需SQL参数的情况
	 * @author JianFeng Zhang(张建锋) 
	 * @data   2017-04-16 下午5:41:41
	 * @param sqlId SQL语句ID,即文件中的namespace.SQLID
	 * @param pageParm  分页参数
	 * @return Page对象
	 */
	public DtPage selectFromXMLDtPage(String sqlId,DtParm pageParm){
		//分页查询
		String orderBy = pageParm.getOrderBy();
		if (pageParm.getOrderable() && !"".equals(orderBy)){
			PageHelper.offsetPage(pageParm.getStart(),pageParm.getLength(),orderBy);
		}else{
			PageHelper.offsetPage(pageParm.getStart(),pageParm.getLength());
		}
        List<Map> data = baseDao.selectFromXML(sqlId);
        PageInfo page = new PageInfo(data);
        int total = ((Number)page.getTotal()).intValue();
        
        DtPage<Map> result = new DtPage<Map>();
        result.setDraw(pageParm.getDraw());
        result.setData(data);
        result.setRecordsTotal(total);
        result.setRecordsFiltered(total);        
    	return result;
	}
}
